From: Florian Müllner Date: Thu, 29 Nov 2012 17:20:43 +0000 (+0100) Subject: sessionMode: Make loading of external modes asynchronous X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~5306 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=92083eaf76fc7a5c2ecdd182896583ab5026ddf0;p=gnome-shell.git sessionMode: Make loading of external modes asynchronous Blocking IO on startup is bad m'kay ... https://bugzilla.gnome.org/show_bug.cgi?id=689304 --- diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js index ed515dc00..eacefd094 100644 --- a/js/ui/sessionMode.js +++ b/js/ui/sessionMode.js @@ -3,8 +3,10 @@ const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Lang = imports.lang; +const Mainloop = imports.mainloop; const Signals = imports.signals; +const FileUtils = imports.misc.fileUtils; const Main = imports.ui.main; const Params = imports.misc.params; @@ -106,68 +108,48 @@ const _modes = { } }; -function _getModes() { - let modes = _modes; - let dataDirs = GLib.get_system_data_dirs(); - for (let i = 0; i < dataDirs.length; i++) { - let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'modes']); - let dir = Gio.file_new_for_path(path); - - try { - dir.query_info('standard:type', Gio.FileQueryInfoFlags.NONE, null); - } catch (e) { - continue; - } - - _getModesFromDir(dir, modes); - } - return modes; +function _getModes(modesLoadedCallback) { + FileUtils.collectFromDatadirsAsync('modes', + { processFile: _loadMode, + loadedCallback: modesLoadedCallback, + data: _modes }); } -function _getModesFromDir(dir, modes) { - let fileEnum; +function _loadMode(file, info, loadedData) { + let name = info.get_name(); + let suffix = name.indexOf('.json'); + let modeName = suffix == -1 ? name : name.slice(name, suffix); + + if (loadedData.hasOwnProperty(modeName)) + return; + + let fileContent, success, tag, newMode; try { - fileEnum = dir.enumerate_children('standard::*', - Gio.FileQueryInfoFlags.NONE, null); + [success, fileContent, tag] = file.load_contents(null); + newMode = JSON.parse(fileContent); } catch(e) { return; } - let info; - while ((info = fileEnum.next_file(null)) != null) { - let name = info.get_name(); - let suffix = name.indexOf('.json'); - let modeName = suffix == -1 ? name : name.slice(name, suffix); - - if (modes.hasOwnProperty(modeName)) - continue; - - let file = dir.get_child(name); - let fileContent, success, tag, newMode; - try { - [success, fileContent, tag] = file.load_contents(null); - newMode = JSON.parse(fileContent); - } catch(e) { - continue; - } - - modes[modeName] = {}; - let propBlacklist = ['unlockDialog']; - for (let prop in modes[DEFAULT_MODE]) { - if (newMode[prop] !== undefined && - propBlacklist.indexOf(prop) == -1) - modes[modeName][prop]= newMode[prop]; - } - modes[modeName]['isPrimary'] = true; + loadedData[modeName] = {}; + let propBlacklist = ['unlockDialog']; + for (let prop in loadedData[DEFAULT_MODE]) { + if (newMode[prop] !== undefined && + propBlacklist.indexOf(prop) == -1) + loadedData[modeName][prop]= newMode[prop]; } - fileEnum.close(null); + loadedData[modeName]['isPrimary'] = true; } function listModes() { - let modes = Object.getOwnPropertyNames(_getModes()); - for (let i = 0; i < modes.length; i++) - if (_modes[modes[i]].isPrimary) - print(modes[i]); + _getModes(function(modes) { + let names = Object.getOwnPropertyNames(modes); + for (let i = 0; i < names.length; i++) + if (_modes[names[i]].isPrimary) + print(names[i]); + Mainloop.quit('listModes'); + }); + Mainloop.run('listModes'); } const SessionMode = new Lang.Class({ @@ -175,11 +157,18 @@ const SessionMode = new Lang.Class({ _init: function() { global.connect('notify::session-mode', Lang.bind(this, this._sync)); - this._modes = _getModes(); - let mode = this._modes[global.session_mode].isPrimary ? global.session_mode - : 'user'; - this._modeStack = [mode]; + this._modes = _modes; + this._modeStack = [DEFAULT_MODE]; this._sync(); + + _getModes(Lang.bind(this, function(modes) { + this._modes = modes; + let primary = modes[global.session_mode] && + modes[global.session_mode].isPrimary; + let mode = primary ? global.session_mode : 'user'; + this._modeStack = [mode]; + this._sync(); + })); }, pushMode: function(mode) {